home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * @(#)tfm.c 2.7 EPA
- *
- * Copyright 1987,1988 Pat J Monardo
- *
- * Redistribution of this file is permitted through
- * the specifications in the file COPYING.
- *
- *
- */
-
- #include "tex.h"
- #include "box.h"
- #include "scan.h"
- #include "token.h"
- #include "tokenstack.h"
- #include "file.h"
- #include "tfm.h"
-
- /*
- * Read and check the font data;
- * If the TFM file is malformed, goto bad_tfm;
- * If there is no room for this font, say so and goto done;
- * otherwise, incr(font_ptr) and goto done
- */
-
- byte_file tfm_file;
-
- qqqq null_character;
-
- ptr fmem_ptr;
- mword font_info[FONT_MEM_SIZE];
-
- fnt font_ptr = FONT_BASE;
- qqqq font_check[FONT_MAX];
- scal font_size[FONT_MAX];
- scal font_dsize[FONT_MAX];
- hword font_params[FONT_MAX];
- str font_name[FONT_MAX];
- str font_area[FONT_MAX];
- byte font_bc[FONT_MAX];
- byte font_ec[FONT_MAX];
- ptr font_glue[FONT_MAX];
- bool font_used[FONT_MAX];
- int hyphen_char[FONT_MAX];
- int skew_char[FONT_MAX];
- ptr char_base[FONT_MAX];
- ptr width_base[FONT_MAX];
- ptr height_base[FONT_MAX];
- ptr depth_base[FONT_MAX];
- ptr italic_base[FONT_MAX];
- ptr lig_kern_base[FONT_MAX];
- ptr kern_base[FONT_MAX];
- ptr exten_base[FONT_MAX];
- ptr param_base[FONT_MAX];
-
- #define start_font_error_message() \
- {print_err("Font "); sprint_cs(u); \
- print_char('='); print_file_name(nom, aire, null_str); \
- if (s >= 0) {print(" at "); print_scaled(s); print("pt");} \
- else if (s != -1000) {print(" scaled "); print_int(-s);}}
-
- #define get_font_byte() \
- (font_byte = getc(tfm_file))
-
- #define read_sixteen(X) \
- {get_font_byte(); X = font_byte; \
- if (X > 127) goto bad_tfm; \
- get_font_byte(); X = (X) * 0400 + font_byte;}
-
- #define store_four_quarters(Q) \
- {a = get_font_byte(); b = get_font_byte(); \
- c = get_font_byte(); d = get_font_byte(); \
- qw.b0 = qi(a); qw.b1 = qi(b); \
- qw.b2 = qi(c); qw.b3 = qi(d); Q = qw;}
-
- #define store_scaled(S) \
- {a = get_font_byte(); b = get_font_byte(); \
- c = get_font_byte(); d = get_font_byte(); \
- sw = ((((d * z) / 0400) + (c * z)) / 0400 + (b * z)) / beta; \
- if (a == 0) S = sw; else if (a == 255) S = sw - alpha; \
- else goto bad_tfm;}
-
- #define check_byte_range(C) {if (C < bc || C > ec) goto bad_tfm;}
- #define ccbwo (k + bc - fmem_ptr)
- #define adjust(I) (I[f] = qo(I[f]))
-
- fnt
- read_font_info (u, nom, aire, s)
- fnt u;
- str nom;
- str aire;
- scal s;
- {
- byte a;
- byte b;
- byte c;
- byte d;
- fnt f;
- fnt g;
- int k;
- scal z;
- hword bc;
- hword ec;
- hword lf;
- hword lh;
- hword nd;
- hword ne;
- hword nh;
- hword ni;
- hword nk;
- hword nl;
- hword np;
- hword nw;
- qqqq qw;
- scal sw;
- val alpha;
- hword beta;
- bool file_opened;
- byte font_byte;
- qqqq dev_null;
- /*
- * Open tfm_file for input
- */
- g = null_font;
- file_opened = FALSE;
- pack_file_name(nom, aire, str_tfm);
- if ((tfm_file = b_open_in()) == NULL)
- goto bad_tfm;
- file_opened = TRUE;
- /*
- * Read the TFM size fields
- */
- read_sixteen(lf);
- read_sixteen(lh);
- read_sixteen(bc);
- read_sixteen(ec);
- if (bc > ec + 1 || ec > 255) goto bad_tfm;
- read_sixteen(nw);
- read_sixteen(nh);
- read_sixteen(nd);
- read_sixteen(ni);
- read_sixteen(nl);
- read_sixteen(nk);
- read_sixteen(ne);
- read_sixteen(np);
- if (lf != 6 + lh + (ec - bc + 1) + nw + nh + nd + ni + nl + nk + ne + np)
- goto bad_tfm;
- /*
- * Use size fields to allocate font information
- */
- lf = lf - 6 - lh;
- if (np < 7) lf += 7 - np;
- if (font_ptr == FONT_MAX-1 || fmem_ptr + lf >= FONT_MEM_SIZE) {
- start_font_error_message();
- print(" not loaded: No more room.");
- help_font();
- error();
- goto done;
- }
-
- f = font_ptr + 1;
- char_base[f] = fmem_ptr - bc;
- width_base[f] = char_base[f] + ec + 1;
- height_base[f] = width_base[f] + nw;
- depth_base[f] = height_base[f] + nh;
- italic_base[f] = depth_base[f] + nd;
- lig_kern_base[f] = italic_base[f] + ni;
- kern_base[f] = lig_kern_base[f] + nl;
- exten_base[f] = kern_base[f] + nk;
- param_base[f] = exten_base[f] + ne;
- /*
- * Read the TFM header
- */
- if (lh < 2) goto bad_tfm;
- store_four_quarters(font_check[f]);
- read_sixteen(z);
- get_font_byte();
- z = z * 0400 + font_byte;
- get_font_byte();
- z = z * 020 + font_byte / 020;
- if (z < UNITY) goto bad_tfm;
- while (lh > 2) {
- store_four_quarters(dev_null);
- decr(lh);
- }
- font_dsize[f] = z;
- if (s != -1000) {
- if (s >= 0)
- z = s;
- else z = xn_over_d(z, -s, 1000L);
- }
- font_size[f] = z;
- /*
- * Read character data
- */
- for (k = fmem_ptr; k < width_base[f]; incr(k)) {
- store_four_quarters(font_info[k].qqqq);
- if (a >= nw || b / 020 >= nh || b % 020 >= nd || c / 4 > ni)
- goto bad_tfm;
- switch (c % 4)
- {
- case LIG_TAG:
- if (d >= nl) goto bad_tfm;
- break;
-
- case EXT_TAG:
- if (d >= ne) goto bad_tfm;
- break;
-
- case LIST_TAG:
- check_byte_range(d);
- while (d < ccbwo) {
- qw = char_info(f, d);
- if (char_tag(qw) != LIST_TAG)
- goto not_found;
- d = qo(rem_byte(qw));
- }
- if (d == ccbwo) goto bad_tfm;
- break;
-
- not_found:
- break;
- }
- }
- /*
- * Read box dimensions
- */
- alpha = 16;
- while (z >= 040000000) {
- z >>= 1;
- alpha <<= 1;
- }
- beta = 256 / alpha;
- alpha *= z;
- for (k = width_base[f]; k < lig_kern_base[f]; incr(k))
- store_scaled(font_info[k].sc);
- if (font_info[width_base[f]].sc != 0)
- goto bad_tfm;
- if (font_info[height_base[f]].sc != 0)
- goto bad_tfm;
- if (font_info[depth_base[f]].sc != 0)
- goto bad_tfm;
- if (font_info[italic_base[f]].sc != 0)
- goto bad_tfm;
- /*
- * Read ligature/kern programs
- */
- for (k = lig_kern_base[f]; k < kern_base[f]; incr(k)) {
- store_four_quarters(font_info[k].qqqq);
- check_byte_range(b);
- if (c < KERN_FLAG) {
- check_byte_range(d);
- } else if (d >= nk)
- goto bad_tfm;
- }
- if (nl > 0 && a < STOP_FLAG)
- goto bad_tfm;
-
- for (k = kern_base[f]; k < exten_base[f]; incr(k))
- store_scaled(font_info[k].sc);
- /*
- * Read extensible character recipes
- */
- for (k = exten_base[f]; k < param_base[f]; incr(k)) {
- store_four_quarters(font_info[k].qqqq);
- if (a != 0)
- check_byte_range(a);
- if (b != 0)
- check_byte_range(b);
- if (c != 0)
- check_byte_range(c);
- check_byte_range(d);
- }
- /*
- * Read font parameters
- */
- for (k = 1; k <= np; incr(k)) {
- if (k == 1) {
- get_font_byte();
- sw = font_byte;
- if (sw > 127)
- sw -= 256;
- get_font_byte();
- sw = sw * 0400 + font_byte;
- get_font_byte();
- sw = sw * 0400 + font_byte;
- get_font_byte();
- font_info[param_base[f]].sc = sw * 020 + font_byte / 020;
- } else {
- store_scaled(font_info[param_base[f] + k - 1].sc);
- }
- }
- if (feof(tfm_file))
- goto bad_tfm;
-
- for (k = np + 1; k <= 7; incr(k))
- font_info[param_base[f] + k - 1].sc = 0;
- /*
- * Make final adjustments and done
- */
- font_params[f] = (np >= 7) ? np : 7;
- hyphen_char[f] = default_hyphen_char;
- skew_char[f] = default_skew_char;
- font_name[f] = nom;
- font_area[f] = aire;
- font_bc[f] = bc;
- font_ec[f] = ec;
- font_glue[f] = NULL;
- adjust(char_base);
- adjust(width_base);
- adjust(lig_kern_base);
- adjust(kern_base);
- adjust(exten_base);
- decr(param_base[f]);
- fmem_ptr += lf;
- font_ptr = f;
- g = f;
- goto done;
-
- bad_tfm:
- start_font_error_message();
- if (file_opened)
- print(" not loadable: Bad metric (TFM) file");
- else print(" not loadable: Metric (TFM) file not found");
- help_tfm();
- error();
- return null_font;
-
- done:
- b_close(tfm_file);
- return g;
- }
-
- scan_font_ident ()
- {
- fnt f;
- int m;
-
- get_nbx_token();
- if (cur_cmd == DEF_FONT) {
- f = cur_font;
- } else if (cur_cmd == SET_FONT) {
- f = cur_chr;
- } else if (cur_cmd == DEF_FAMILY) {
- m = cur_chr;
- scan_four_bit_int();
- f = equiv(m + cur_val);
- } else {
- print_err("Missing font identifier");
- help_font_cs();
- back_error();
- f = null_font;
- }
- cur_val = f;
- }
-
- find_font_dimen (writing)
- bool writing;
- {
- fnt f;
- int n;
-
- scan_int();
- n = cur_val;
- scan_font_ident();
- f = cur_val;
- if (n <= 0) {
- cur_val = fmem_ptr;
- } else {
- if (writing &&
- n <= SPACE_SHRINK_CODE &&
- n >= SPACE_CODE &&
- font_glue[f] != NULL) {
- delete_glue_ref(font_glue[f]);
- font_glue[f] = NULL;
- }
- if (n > font_params[f]) {
- if (f < font_ptr) {
- cur_val = fmem_ptr;
- } else {
- do {
- if (fmem_ptr == FONT_MEM_SIZE)
- overflow("font_memory", FONT_MEM_SIZE);
- font_info[fmem_ptr].sc = 0;
- incr(fmem_ptr);
- incr(font_params[f]);
- } while (n != font_params[f]);
- cur_val = fmem_ptr - 1;
- }
- } else {
- cur_val = n + param_base[f];
- }
- }
- if (cur_val == fmem_ptr) {
- print_nl("! Font ");
- print_esc("");
- print_str(font_id_text(f));
- print(" has only ");
- print_int(font_params[f]);
- print(" fontdimen parameters");
- help_font_param();
- error();
- }
- }
-
- char_warning (f, c)
- fnt f;
- byte c;
- {
- if (tracing_lost_chars > 0) {
- begin_diagnostic();
- print_nl("Missing character: There is no ");
- print_ASCII(c);
- print(" in font ");
- print_str(font_name[f]);
- print_char('!');
- end_diagnostic(FALSE);
- }
- }
-
- ptr
- new_character (f, c)
- fnt f;
- byte c;
- {
- ptr p;
-
- if (font_bc[f] <= c && font_ec[f] >= c) {
- if (char_exists(char_info(f, qi(c)))) {
- p = get_avail();
- font(p) = f;
- character(p) = qi(c);
- return p;
- }
- }
- char_warning(f, c);
- return NULL;
- }
-
- init_tfm ()
- {
- fmem_ptr = 7;
- font_params[0] = 7;
- font_bc[0] = 1;
- font_glue[0] = zero_glue;
- hyphen_char[0] = '-';
- skew_char[0] = -1;
- param_base[0] = -1;
- }
-
- /*
- * Help text
- */
-
- help_font ()
- {
- help4("I'm afraid I won't be able to make use of this font,",
- "because my memory for character-size data is too small.",
- "If you're really stuck, ask a wizard to enlarge me.",
- "Or maybe try `I\\font<same font id>=<name of loaded font>'.");
- }
-
- help_tfm ()
- {
- help5("I wasn't able to read the size data for this font,",
- "so I will ignore the font specification.",
- "[Wizards can fix TFM files using TFtoPL/PLtoTF.]",
- "You might try inserting a different font spec;",
- "e.g., type `I\\font<same font id>=<substitute font name>'.");
- }
-
- help_font_param ()
- {
- help2("To increase the number of font parameters, you must",
- "use \\fontdimen immediately after the \\font is loaded.");
- }
-
- help_font_cs ()
- {
- help2("I was looking for a control sequence whose",
- "current meaning has been defined by \\font.");
- }
-